package com.liushuo.view;

import com.liushuo.controller.ExerciseSetController;
import com.liushuo.entity.ExerciseSet;
import com.liushuo.util.GenerateChartUtil;
import com.liushuo.util.GeneratePieChartUtil;
import com.liushuo.util.JFreeChartUtil;
import com.liushuo.util.ThreadLocalUtil;
import org.jdesktop.swingx.JXDatePicker;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDate;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

public class ScoreUI extends JFrame {
    private final JXDatePicker startDatePicker;
    private final JXDatePicker endDatePicker;
    private final JScrollPane scrollPane;

    private List<JPanel> exerciseSetPanels;
    private List<ExerciseSet> exerciseSets = new ArrayList<>();

    private final ExerciseSetController exerciseSetController = new ExerciseSetController();

    private final String userId = ThreadLocalUtil.getUserId();

    public ScoreUI() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
                 | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        Font font = new Font("微软雅黑", Font.PLAIN, 20);

        setTitle("口算练习器-成绩统计");

        setBackground(Color.CYAN);
        setBounds(600, 400, 1000, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        JPanel questionPanel = new JPanel();
        questionPanel.setBackground(Color.CYAN);
        questionPanel.setLayout(new BoxLayout(questionPanel, BoxLayout.Y_AXIS));

        scrollPane = new JScrollPane(questionPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        add(scrollPane, BorderLayout.CENTER);

        JPanel rightPanel = new JPanel();
        rightPanel.setBackground(Color.YELLOW);
        rightPanel.setPreferredSize(new Dimension(200, 0));
        rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
        rightPanel.setBorder(BorderFactory.createEmptyBorder(20, 10, 20, 10));

        JLabel Label4 = new JLabel("选择开始日期: ");
        Label4.setFont(font);
        Label4.setAlignmentX(Component.CENTER_ALIGNMENT);
        Label4.setMaximumSize(new Dimension(180, 40));
        rightPanel.add(Label4);
        rightPanel.add(Box.createVerticalStrut(5));

        startDatePicker = new JXDatePicker();
        startDatePicker.setFont(font);
        startDatePicker.setFormats("yyyy-MM-dd");
        startDatePicker.setDate(new Date());
        startDatePicker.setAlignmentX(Component.CENTER_ALIGNMENT);
        startDatePicker.setMaximumSize(new Dimension(180, 40));
        rightPanel.add(startDatePicker);
        rightPanel.add(Box.createVerticalStrut(10));


        JLabel Label5 = new JLabel("选择结束日期: ");
        Label5.setFont(font);
        Label5.setAlignmentX(Component.CENTER_ALIGNMENT);
        Label5.setMaximumSize(new Dimension(180, 40));
        rightPanel.add(Label5);
        rightPanel.add(Box.createVerticalStrut(5));

        endDatePicker = new JXDatePicker();
        endDatePicker.setFont(font);
        endDatePicker.setFormats("yyyy-MM-dd");
        endDatePicker.setDate(new Date());
        endDatePicker.setAlignmentX(Component.CENTER_ALIGNMENT);
        endDatePicker.setMaximumSize(new Dimension(180, 40));
        rightPanel.add(endDatePicker);
        rightPanel.add(Box.createVerticalStrut(20));


        JButton checkButton = new JButton("查看成绩");
        checkButton.setFont(font);
        checkButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        checkButton.setMaximumSize(new Dimension(180, 40));
        checkButton.addActionListener(new ScoreUI.ViewScoreButtonListener());
        rightPanel.add(checkButton);
        rightPanel.add(Box.createVerticalStrut(20));

        JButton clearButton = new JButton("清空题目");
        clearButton.setFont(font);
        clearButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        clearButton.setMaximumSize(new Dimension(180, 40));
        clearButton.addActionListener(new ScoreUI.ClearButtonListener());
        rightPanel.add(clearButton);
        rightPanel.add(Box.createVerticalStrut(20));

        JButton lineButton = new JButton("生成折线图");
        lineButton.setFont(font);
        lineButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        lineButton.setMaximumSize(new Dimension(180, 40));
        lineButton.addActionListener(new ScoreUI.LineButtonListener());
        rightPanel.add(lineButton);
        rightPanel.add(Box.createVerticalStrut(20));

        JButton pieButton = new JButton("生成饼状图");
        pieButton.setFont(font);
        pieButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        pieButton.setMaximumSize(new Dimension(180, 40));
        pieButton.addActionListener(new ScoreUI.PieButtonListener());
        rightPanel.add(pieButton);
        rightPanel.add(Box.createVerticalStrut(20));

        JButton GoBackButton = new JButton("返回");
        GoBackButton.setFont(font);
        GoBackButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        GoBackButton.setMaximumSize(new Dimension(180, 40));
        GoBackButton.addActionListener(new ScoreUI.GoBackButtonListener());
        GoBackButton.setAlignmentY(Component.BOTTOM_ALIGNMENT);

        rightPanel.add(Box.createVerticalGlue());
        rightPanel.add(GoBackButton);

        add(rightPanel, BorderLayout.EAST);

        setVisible(true);
    }

    private class ViewScoreButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            Date startDate = startDatePicker.getDate();
            Date endDate = endDatePicker.getDate();
            java.sql.Date startDateSql = new java.sql.Date(startDate.getTime());
            java.sql.Date endDateSql = new java.sql.Date(endDate.getTime());
            exerciseSets = exerciseSetController.getExerciseSetByUserIdAndDate(userId, startDateSql, endDateSql);
            if (exerciseSets.isEmpty()) {
                JOptionPane.showMessageDialog(ScoreUI.this, "没有成绩记录", "提示", JOptionPane.INFORMATION_MESSAGE);
                return;
            }
            displayExerciseSets(exerciseSets);
        }
    }

    private class ClearButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            clearExerciseSets();
        }
    }

    private class GoBackButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            int result = JOptionPane.showConfirmDialog(ScoreUI.this, "确定要退出吗？", "提示", JOptionPane.YES_NO_OPTION);
            if (result == JOptionPane.YES_OPTION) {
                dispose();
                new RouterUI();
            } else if (result == JOptionPane.NO_OPTION) {
                return;
            }
        }
    }

    private void displayExerciseSets(List<ExerciseSet> exerciseSets) {
        clearExerciseSets();

        exerciseSetPanels = new ArrayList<>();
        JPanel headerPanel = new JPanel();
        headerPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        headerPanel.setBackground(Color.CYAN);
        JLabel headerLabel = new JLabel("序号 题目范围 年级 分数 日期");
        headerLabel.setFont(new Font("微软雅黑", Font.PLAIN, 20));
        headerPanel.add(headerLabel);
        ((JPanel) scrollPane.getViewport().getView()).add(headerPanel);
        for (ExerciseSet exerciseSet : exerciseSets) {
            JPanel exerciseSetPanel = new JPanel();
            exerciseSetPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
            exerciseSetPanel.setBackground(Color.CYAN);

            String exerciseSetText = "[" + (exerciseSets.indexOf(exerciseSet) + 1) + "] " + exerciseSet.getStartQuestionId() + "~" +
                                        exerciseSet.getEndQuestionId() + "  " + exerciseSet.getGradeLevel()+ "级  " +
                                        exerciseSet.getScore() + "分 " + exerciseSet.getCreateTime();
            JLabel exerciseSetLabel = new JLabel(exerciseSetText);
            exerciseSetLabel.setFont(new Font("微软雅黑", Font.PLAIN, 20));
            exerciseSetPanel.add(exerciseSetLabel);

            exerciseSetPanels.add(exerciseSetPanel);
            ((JPanel) scrollPane.getViewport().getView()).add(exerciseSetPanel);
            ((JPanel) scrollPane.getViewport().getView()).add(Box.createVerticalStrut(20));
        }
        revalidate();
        repaint();
    }

    private void clearExerciseSets() {
        if (exerciseSetPanels != null) {
            JViewport viewport = scrollPane.getViewport();
            JPanel panel = (JPanel) viewport.getView();
            panel.removeAll();
            revalidate();
            repaint();

            exerciseSetPanels.clear();
        }
    }

    private class LineButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (exerciseSets.isEmpty()) {
                JOptionPane.showMessageDialog(ScoreUI.this, "请先选择查看成绩", "提示", JOptionPane.INFORMATION_MESSAGE);
                return;
            }

            //x轴名称列表
            List<String> xAxisNameList = new ArrayList<>();
            for (ExerciseSet exerciseSet : exerciseSets){
                if (exerciseSet.getScore() != null && !exerciseSet.getScore().equals("0") && exerciseSet.getGradeLevel() != null) {
                    LocalDate date = LocalDate.from(exerciseSet.getCreateTime().toLocalDateTime());
//                    String date = String.valueOf(exerciseSet.getCreateTime());
                    xAxisNameList.add(String.valueOf(date));
                }
            }
            xAxisNameList = xAxisNameList.stream().distinct().collect(Collectors.toList());
            System.out.println(xAxisNameList);
            Map<String, List<String>> gradeLevelMap = new HashMap<>();
            gradeLevelMap.put("1", new ArrayList<>());
            gradeLevelMap.put("2", new ArrayList<>());
            gradeLevelMap.put("3", new ArrayList<>());
            gradeLevelMap.put("4", new ArrayList<>());
            gradeLevelMap.put("5", new ArrayList<>());
            gradeLevelMap.put("6", new ArrayList<>());
            for (ExerciseSet exerciseSet : exerciseSets) {
                if (exerciseSet.getScore() == null || exerciseSet.getScore().equals("0") || exerciseSet.getGradeLevel() == null) {
                    continue;
                }
                String date = String.valueOf(LocalDate.from(exerciseSet.getCreateTime().toLocalDateTime()));
                int index = xAxisNameList.indexOf(date);
                if (gradeLevelMap.get(exerciseSet.getGradeLevel()).size() < index) {
                    for (int i = gradeLevelMap.get(exerciseSet.getGradeLevel()).size(); i <= index; i++) {
                        gradeLevelMap.get(exerciseSet.getGradeLevel()).add("0");
                    }
                }
                gradeLevelMap.get(exerciseSet.getGradeLevel()).add(exerciseSet.getScore());
            }
            for (Map.Entry<String, List<String>> entry : gradeLevelMap.entrySet()) {
                if (!entry.getValue().isEmpty()) {
                    if (entry.getValue().size() < xAxisNameList.size()) {
                        for (int i = entry.getValue().size(); i < xAxisNameList.size(); i++) {
                            entry.getValue().add("0");
                        }
                    }
                }
            }

            //图例名称列表
            List<String> legendNameList = new ArrayList<>();
            //数据列表
            List<String> gradeList = new ArrayList<>(Arrays.asList("一级", "二级", "三级", "四级", "五级", "六级"));
            List<List<Object>> dataList = new ArrayList<>();
            for (Map.Entry<String, List<String>> entry : gradeLevelMap.entrySet()) {
                if (!entry.getValue().isEmpty()) {
                    legendNameList.add(gradeList.get(Integer.parseInt(entry.getKey())-1));
                    dataList.add(new ArrayList<>(entry.getValue()));
                }
            }
            System.out.println(legendNameList);
            System.out.println(dataList);

            try {
                JFreeChart chart = GenerateChartUtil.createLineChart("各级变化图", legendNameList, xAxisNameList
                        , dataList, JFreeChartUtil.createChartTheme("宋体"), "y轴", "x轴");
                JFrame chartFrame = new JFrame("日期成绩变化折线图");
                chartFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                chartFrame.setSize(800, 600);
                chartFrame.setLocationRelativeTo(null);
                chartFrame.getContentPane().add(new ChartPanel(chart));
                chartFrame.pack();
                chartFrame.setVisible(true);

            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    private class PieButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (exerciseSets.isEmpty()) {
                JOptionPane.showMessageDialog(ScoreUI.this, "请先选择查看成绩", "提示", JOptionPane.INFORMATION_MESSAGE);
                return;
            }
            Map<String, List<String>> gradeLevelMap = new HashMap<>();
            for (ExerciseSet exerciseSet : exerciseSets) {
                if (exerciseSet.getScore() == null || exerciseSet.getScore().equals("0") || exerciseSet.getGradeLevel() == null) {
                    continue;
                }
                if ( !gradeLevelMap.containsKey(exerciseSet.getGradeLevel())) {
                    gradeLevelMap.put(exerciseSet.getGradeLevel(), new ArrayList<>());
                }
                gradeLevelMap.get(exerciseSet.getGradeLevel()).add(exerciseSet.getScore());
            }
            System.out.println(gradeLevelMap);

            List<String> gradeList = new ArrayList<>(Arrays.asList("一级", "二级", "三级", "四级", "五级", "六级"));
            //图例名称列表
            List<String> legendNameList = new ArrayList<>();

            List<Integer> temp = new ArrayList<>();
            for (Map.Entry<String, List<String>> entry : gradeLevelMap.entrySet()) {
                if (entry.getValue().isEmpty()) {
                    continue;
                }
                legendNameList.add(gradeList.get(Integer.parseInt(entry.getKey())-1));
                List<String> scoreList = entry.getValue();
                int avgScore = 0;
                for (String score : scoreList) {
                    avgScore += Integer.parseInt(score);
                }
                avgScore /= scoreList.size();
                temp.add(avgScore);
            }
            //数据列表
            List<Object> dataList = new ArrayList<>(temp);
            System.out.println(legendNameList);
            System.out.println(dataList);


            //图例背景颜色列表
            List<Color> legendColorList = new ArrayList<>(Arrays.asList(Color.YELLOW, Color.GRAY, Color.green, Color.cyan, Color.ORANGE));
            //偏离百分比数据
            List<Double> explodePercentList = new ArrayList<>(Arrays.asList(0.1, 0.1, 0.1, 0.1, 0.1));
            try {
                JFreeChart chart = GeneratePieChartUtil.createPieChart("各级占比情况", legendNameList, dataList
                        ,JFreeChartUtil.createChartTheme("宋体"), legendColorList, explodePercentList);

                JFrame chartFrame = new JFrame("各年级平均分数占比饼图");
                chartFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                chartFrame.setSize(800, 600);
                chartFrame.setLocationRelativeTo(null);
                chartFrame.getContentPane().add(new ChartPanel(chart));
                chartFrame.pack();
                chartFrame.setVisible(true);

            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }

        }
    }


}
